-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix soundness issue for replace_range
and range
#81169
Fix soundness issue for replace_range
and range
#81169
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #81159) made this pull request unmergeable. Please resolve the merge conflicts. |
@@ -1553,18 +1553,21 @@ impl String { | |||
// Replace_range does not have the memory safety issues of a vector Splice. | |||
// of the vector version. The data is just plain bytes. | |||
|
|||
match range.start_bound() { | |||
let start = range.start_bound(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think comments explaining this change might be beneficial here as well. With or without a big // WARNING: do not inline this variable
:)
Included(&n) => assert!(self.is_char_boundary(n + 1)), | ||
Excluded(&n) => assert!(self.is_char_boundary(n)), | ||
Unbounded => {} | ||
}; | ||
|
||
unsafe { self.as_mut_vec() }.splice(range, replace_with.bytes()); | ||
// Using `range` again would be unsound (#81138) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, here it is. Hmm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bugadani Do you think another comment would be helpful? I added one where I thought it would make the most sense, since adding one above let start
but not let end
is a little weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think more comments wouldn't hurt 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true 😛
@@ -25,7 +25,10 @@ where | |||
K: Borrow<Q>, | |||
R: RangeBounds<Q>, | |||
{ | |||
match (range.start_bound(), range.end_bound()) { | |||
// Using `range` again would be unsound (#81138) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Using `range` again would be unsound (#81138) | |
// Using `range` again would be unsound (#81138) | |
// We assume the bounds reported by `range` remain the same, but | |
// an adversarial implementation could change between calls |
I've just left a few comments. It would be good to include the |
Yes, good idea. |
@dylni This looks good to me! Would you like to squash these down then we should be good to go. |
Thanks @KodrAus! Is this what you had in mind? Squashing is a little awkward with merge commits. |
@bors r+ p=1 |
📌 Commit b96063c has been approved by |
That's it, thanks! A rebase and squash is what I'd meant. We try to avoid merge commits in PRs and leave that to bors to handle. Thanks for fixing this up 🙇 |
☀️ Test successful - checks-actions |
Oh, thanks, that makes sense. |
Useful and inspirational, but I feel the need to point out that you didn't entirely plug that hole, and probably nobody can. Unlike |
@ssomers I think that's ok. If an impl used by |
@dylni I agree, but that means there was no unsoundness in BTreeMap's use of start_bound/end_bound, is what I realized this week. How many times these functions are called or what they return doesn't matter for unsoundness. It's what the various invocations of the lookup type's This PR of course still includes a welcome fix to avoid BTreeMap from appearing to misbehave when the range misbehaves. If there was a possibility of unsoundness in BTreeMap, that possibility is still there. And I can't find it. |
Not sure how you arrived in |
@ssomers
I agree, but this was surprising. I think I'll change the comments a little there to make it clearer for people reading it in the future. |
…ark-Simulacrum BTreeMap: test all borrowing interfaces and test more chaotic order behavior Inspired by rust-lang#81169, test what happens if you mess up order of the type with which you search (as opposed to the key type). r? `@Mark-Simulacrum`
…ents, r=m-ou-se Clarify BTree `range_search` comments These comments were added by rust-lang#81169. However, the soundness issue [might not be exploitable here](rust-lang#81169 (comment)), so the comments should be updated. cc `@ssomers`
…-ou-se Clarify BTree `range_search` comments These comments were added by #81169. However, the soundness issue [might not be exploitable here](rust-lang/rust#81169 (comment)), so the comments should be updated. cc `@ssomers`
Fixes #81138 by only calling
start_bound
andend_bound
once.I also fixed the same issue for
BTreeMap::range
andBTreeSet::range
.